#include <iostm8s103f3.h>

#define UART1_FLAG_TXE  (unsigned char)0x80  // Tx Data Register Empty flag
#define UART1_FLAG_RXNE (unsigned char)0x20  // Rx Data Register Not Empty flag


static void delay(unsigned long nCount)
{
  while (nCount != 0) {
    nCount--;
  }
}

/*! \brief send a byte.
 *
 *  Puts a byte in TX buffer and starts uart TX interrupt.
 *  If TX buffer is full it will hang until space.
 *
 *  \param data  Data to be sent.
 */
void uart_SendByte(unsigned char data)
{
  // Loop until the end of transmission
  while (!(UART1_SR & UART1_FLAG_TXE));
  UART1_DR = data;
}

/*! \brief Sends a string.
 *
 *  Loops thru a string and send each byte with uart_SendByte.
 *  If TX buffer is full it will hang until space.
 *
 *  \param Str  String to be sent.
 */
void uart_SendString(unsigned char Str[])
{
  unsigned char n = 0;
  while(Str[n])
    uart_SendByte(Str[n++]);
}

/*! \brief Sends a integer.
 *
 *  Converts a integer to ASCII and sends it using uart_SendByte.
 *  If TX buffer is full it will hang until space.
 *
 *  \param x  Integer to be sent.
 */
void uart_SendInt(int x)
{
  static const char dec[] = "0123456789";
  unsigned int div_val = 10000;

  if (x < 0){
    x = - x;
    uart_SendByte('-');
  }
  while (div_val > 1 && div_val > x)
    div_val /= 10;
  do{
    uart_SendByte (dec[x / div_val]);
    x %= div_val;
    div_val /= 10;
  }while(div_val);
}

int main( void )
{
  // setup clock
  CLK_CKDIVR &= (unsigned char)(~0x18);  // 16MHz high speed internal clock
  
  // setup uart: 115200, 8-n-1
  // reference: Table 54. Baud rate programming and error calculation
  UART1_CR1 = 0x00;  // 1-8-nn, uart enabled, no parity check and interrupt
  UART1_CR2 = 0x0C;  // rx/tx enabled, rx int disabled, tx int disabled
  UART1_CR3 = 0x00;  // 1 stop bits
  UART1_CR5 = 0x00;  // IrDA mode disabled
  UART1_BRR2 = 0x0B;  // 115200 baud rate. must set BRR2 first
  UART1_BRR1 = 0x08;  // 115200 baud rate. must set BRR2 first
  
  while (1) {
    uart_SendString("usart test: ");
    uart_SendInt(123);
    uart_SendByte(' ');
    uart_SendInt(-456);
    uart_SendString("\r\n");
    delay(0xffff);
  }
}
